package com.regedit.aplicacion.provider;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.util.Log;

import com.regedit.aplicacion.dao.DatabaseHelper;
import com.regedit.aplicacion.dao.EntityDao;

public class AplicacionProvider extends ContentProvider {

	public static final String AUTHORITY = "com.regedit.aplicacion.provider.AplicacionProvider";

	private static final UriMatcher uriMatcher;
	private static final int ENTITY = 10;

	static {
		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		uriMatcher.addURI(AUTHORITY, EntityDao.TABLE_NAME, ENTITY);

		// Projections

	}

	private DatabaseHelper dbHelper;
	private SQLiteDatabase sqlDb;

	@Override
	public boolean onCreate() {
		dbHelper = new DatabaseHelper(getContext());
		return true;
	}

	@Override
	public String getType(final Uri uri) {
		switch (uriMatcher.match(uri)) {
		case ENTITY:
			return "E";
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
	}

	@Override
	public Cursor query(final Uri uri, final String[] projection,
			String selection, final String[] selectionArgs,
			final String sortOrder) {

		final SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
		Uri notificationUri;
		String groupBy = null;
		switch (uriMatcher.match(uri)) {
		case ENTITY:
			queryBuilder.setTables(EntityDao.TABLE_NAME);
			notificationUri = uri;
			break;

		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		prepareDatabaseConnection();
		final Cursor c = queryBuilder.query(sqlDb, projection, selection,
				selectionArgs, groupBy, null, sortOrder);
		c.setNotificationUri(getContext().getContentResolver(), notificationUri);
		c.moveToFirst();
		return c;
	}

	@Override
	public Uri insert(final Uri uri, final ContentValues values) {

		prepareDatabaseConnection();
		long insertedRowId = 0;
		String tableName;

		switch (uriMatcher.match(uri)) {
		case ENTITY:
			tableName = EntityDao.TABLE_NAME;
			break;

		default:
			// Replace this with a String value in xml
			Log.e("Invalid uri: ", uri.toString());
			throw new SQLException("Invalid uri: " + uri);
		}

		insertedRowId = sqlDb.insert(tableName, null, values);

		if (insertedRowId > 0) {
			final Uri insertedUri = ContentUris.withAppendedId(uri,
					insertedRowId);

			// Notify a new row is added (i.e. for cursor adapters)
			getContext().getContentResolver().notifyChange(insertedUri, null);
			return insertedUri;
		}

		// Replace this with a String value in xml
		return ContentUris.withAppendedId(uri, 0);
	}

	@Override
	public int update(final Uri uri, final ContentValues values,
			final String selection, final String[] selectionArgs) {
		prepareDatabaseConnection();
		String tableName;
		Uri notificationUri;
		switch (uriMatcher.match(uri)) {
		case ENTITY:
			notificationUri = uri;
			tableName = EntityDao.TABLE_NAME;
			break;

		default:
			// Replace this with a String value in xml
			Log.e("Invalid uri: ", uri.toString());
			throw new SQLException("Invalid uri: " + uri);
		}
		final int rowsAffected = sqlDb.update(tableName, values, selection,
				selectionArgs);
		if (rowsAffected > 0) {
			// Notify a new row is added (i.e. for cursor adapters)
			getContext().getContentResolver().notifyChange(notificationUri,
					null);
			return rowsAffected;
		}

		// Replace this with a String value in xml
		Log.e("Failed to update row: ", uri.toString());
		return 0;
	}

	@Override
	public int delete(final Uri uri, final String selection,
			final String[] selectionArgs) {
		prepareDatabaseConnection();
		String tableName;
		Uri notificationUri = uri;
		switch (uriMatcher.match(uri)) {
		case ENTITY:
			tableName = EntityDao.TABLE_NAME;
			notificationUri = uri;
			break;

		default:
			// Replace this with a String value in xml
			Log.e("Invalid uri: ", uri.toString());
			throw new SQLException("Invalid uri: " + uri);
		}
		final int rowsAffected = sqlDb.delete(tableName, selection,
				selectionArgs);
		if (rowsAffected > 0) {
			// Notify a new row is added (i.e. for cursor adapters)
			getContext().getContentResolver().notifyChange(notificationUri,
					null);
			return rowsAffected;
		}

		return 0;
	}

	private void prepareDatabaseConnection() {
		if (sqlDb == null || !sqlDb.isOpen()) {
			sqlDb = dbHelper.getWritableDatabase();
		}
	}

	@Override
	protected void finalize() throws Throwable {
		sqlDb.close();
		dbHelper.close();
		super.finalize();
	}

	public void deleteAllDatabase() {
		dbHelper.deleteDataFromTables();
	}
}
